import { Component, Input, OnInit } from '@angular/core';
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
import { NzMessageService } from 'ng-zorro-antd/message';
import { _HttpClient } from '@delon/theme';
import { ActivatedRoute } from '@angular/router';
import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { SysKeyValueService } from '@api/sys/service/sysKeyValue.service';
import { SysKeyValue } from '@api/sys/model/sysKeyValue.model';
import { SimpleFormField } from '@api/simple/model/simpleFormField.model';
import { snakeCase } from '@shared/utils/string';
import { SimpleListField } from '@api/simple/model/simpleListField.model';

@Component({
  selector: 'app-simple-list-edit-form',
  templateUrl: './form.component.html',
  styles: [
    `
      nz-select {
        width: 100%;
      }
    `,
  ],
})
export class SimpleListEditFormComponent implements OnInit {
  _data: SimpleFormField[] = [];

  @Input()
  set data(value: SimpleFormField[]) {
    const items = this.fb.array([]);
    value.forEach((item) => {
      items.push(this.createForm());
    });
    this.form.controls.items = items;
    this._data = value;
  }

  get data(): SimpleFormField[] {
    return this._data;
  }

  public form: FormGroup = this.fb.group({
    items: this.fb.array([]),
  });

  fieldTypes: SysKeyValue[] = [];

  widgetTypes: SysKeyValue[] = [];

  operatorTypes: SysKeyValue[] = [];

  formatTypes: SysKeyValue[] = [];

  constructor(
    private msgSrv: NzMessageService,
    public http: _HttpClient,
    protected route: ActivatedRoute,
    private fb: FormBuilder,
    private keyValueSerivice: SysKeyValueService,
  ) {}

  ngOnInit(): void {
    this.keyValueSerivice.findByParentKeyPath('/SIMPLE/FIELD_TYPE').subscribe((res) => (this.fieldTypes = res));
    this.keyValueSerivice.findByParentKeyPath('/SIMPLE/WIDGET_TYPE').subscribe((res) => (this.widgetTypes = res));
    this.keyValueSerivice.findByParentKeyPath('/SIMPLE/OPERATOR_TYPE').subscribe((res) => (this.operatorTypes = res));
    this.keyValueSerivice.findByParentKeyPath('/SIMPLE/FORMAT_TYPE').subscribe((res) => (this.formatTypes = res));
  }

  createForm(): FormGroup {
    return this.fb.group({
      code: [null, [Validators.required]],
      name: [null, [Validators.required]],
      type: [null, [Validators.required]],
      value: [null],
      i18n: [null],
      operator: [null, [Validators.required]],
      widget: [null],
    });
  }

  checked = false;
  loading = false;
  indeterminate = false;
  setOfCheckedId = new Set<string>();

  updateCheckedSet(id: string, checked: boolean): void {
    if (checked) {
      this.setOfCheckedId.add(id);
    } else {
      this.setOfCheckedId.delete(id);
    }
  }

  refreshCheckedStatus(): void {
    const listOfEnabledData = this.data;
    this.checked = listOfEnabledData.every(({ id }) => this.setOfCheckedId.has(id!));
    this.indeterminate = listOfEnabledData.some(({ id }) => this.setOfCheckedId.has(id!)) && !this.checked;
  }

  onItemChecked(id: string, checked: boolean): void {
    this.updateCheckedSet(id, checked);
    this.refreshCheckedStatus();
  }

  onAllChecked(checked: boolean): void {
    this.data.forEach(({ id }) => this.updateCheckedSet(id!, checked));
    this.refreshCheckedStatus();
  }

  drop(event: CdkDragDrop<string[]>): void {
    moveItemInArray(this.data, event.previousIndex, event.currentIndex);
  }

  save() {
    this.form.markAsDirty();
    this.form.updateValueAndValidity();
  }

  addLine(value?: any) {
    if (!value) {
      value = {
        id: `${new Date().getTime()}`,
        type: 'string',
      };
    }
    this.data.push(value);
    let forms = this.form.controls.items as FormArray;
    forms.push(this.createForm());
  }

  deleteLine() {
    if (this.setOfCheckedId.size == 0) {
      this.msgSrv.error('请选择行！');
      return;
    }
    let forms = this.form.controls.items as FormArray;
    this.setOfCheckedId.forEach((id) => {
      const index = this.data.findIndex((item) => {
        id == item.id;
      });
      this.data.splice(index, 1);
      forms.removeAt(index);
    });

    this.setOfCheckedId.clear();
  }

  validate() {
    let forms = this.form.controls.items as FormArray;
    this.data.forEach((o, i) => {
      let form = forms.at(i) as FormGroup;
      Object.values(form.controls).forEach((control) => {
        if (control.invalid) {
          control.markAsDirty();
          control.updateValueAndValidity({ onlySelf: true });
        }
      });
    });
  }

  codeChange(simpleFormField: SimpleFormField) {
    simpleFormField.column = snakeCase(simpleFormField.code);
  }

  addLineByListField(simpleListFields: SimpleListField[]) {
    simpleListFields.forEach((simpleListField) => {
      let simpleFormField = this.data.find((item) => item.code == simpleListField.code);
      if (!simpleFormField) {
        simpleFormField = {};
        simpleFormField.code = simpleListField.code;
        simpleFormField.name = simpleListField.name;
        simpleFormField.column = simpleListField.column;
        simpleFormField.type = simpleListField.type;
        if (simpleListField.type == 'string') {
          simpleFormField.operator = 'like';
          simpleFormField.widget = 'text';
        } else if ((simpleListField.type = 'integer')) {
          simpleFormField.operator = 'between';
          simpleFormField.widget = 'text';
        } else if ((simpleListField.type = 'number')) {
          simpleFormField.operator = 'between';
          simpleFormField.widget = 'text';
        } else if ((simpleListField.type = 'date')) {
          simpleFormField.operator = 'between';
          simpleFormField.widget = 'date';
        } else if ((simpleListField.type = 'time')) {
          simpleFormField.operator = 'between';
          simpleFormField.widget = 'time';
        }
      }
      this.addLine(simpleFormField);
    });
  }
}
